package com.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.entity.Department;
import com.hospital.mapper.DepartmentMapper;
import com.hospital.service.DepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 科室服务实现类
 *
 * @author Hospital Management System
 */
@Slf4j
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
    
    // 继承了IService的所有基础CRUD方法
    // 如果有特殊业务逻辑可以在这里实现
    // 

    @Override
    public Map<String, Object> getDepartmentsWithPagination(String name, String code, Integer status, Integer page, Integer size) {
        log.info("开始查询科室列表，参数：name={}, code={}, status={}, page={}, size={}", 
                 name, code, status, page, size);
        
        try {
            // 创建分页对象
            Page<Department> pageObj = new Page<>(page, size);
            
            // 构建查询条件
            QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("deleted", 0);
            
            // 添加名称筛选
            if (StringUtils.hasText(name)) {
                log.info("添加名称筛选条件: {}", name);
                queryWrapper.like("name", name);
            }
            
            // 添加编码筛选
            if (StringUtils.hasText(code)) {
                log.info("添加编码筛选条件: {}", code);
                queryWrapper.like("code", code);
            }
            
            // 添加状态筛选
            if (status != null) {
                log.info("添加状态筛选条件: {}", status);
                queryWrapper.eq("status", status);
            }
            
            // 按排序号升序
            queryWrapper.orderByAsc("sort_order");
            
            // 打印最终的SQL条件
            String sqlSegment = queryWrapper.getSqlSegment();
            log.info("最终的SQL条件: {}", sqlSegment);
            
            // 执行分页查询
            IPage<Department> pageResult = page(pageObj, queryWrapper);
            
            // 获取分页数据
            List<Department> departments = pageResult.getRecords();
            log.info("查询结果总数: {}", pageResult.getTotal());
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", departments);
            result.put("total", pageResult.getTotal());
            result.put("page", pageResult.getCurrent());
            result.put("size", pageResult.getSize());
            result.put("pages", pageResult.getPages());
            
            return result;
        } catch (Exception e) {
            log.error("查询科室列表时发生错误: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public List<Map<String, Object>> getDepartmentTree(String name, String code, Integer status) {
        log.info("开始查询树形科室列表，参数：name={}, code={}, status={}", name, code, status);
        
        try {
            // 构建查询条件
            QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("deleted", 0);
            
            // 添加名称筛选
            if (StringUtils.hasText(name)) {
                queryWrapper.like("name", name);
            }
            
            // 添加编码筛选
            if (StringUtils.hasText(code)) {
                queryWrapper.like("code", code);
            }
            
            // 添加状态筛选
            if (status != null) {
                queryWrapper.eq("status", status);
            }
            
            // 按层级和排序号排序
            queryWrapper.orderByAsc("level", "sort_order");
            
            // 查询所有符合条件的科室
            List<Department> allDepartments = list(queryWrapper);
            
            // 将科室列表转换为树形结构
            return buildDepartmentTree(allDepartments);
        } catch (Exception e) {
            log.error("查询树形科室列表时发生错误: {}", e.getMessage(), e);
            throw e;
        }
    }
    
    /**
     * 构建科室树形结构
     * @param departments 科室列表
     * @return 树形结构的科室列表
     */
    private List<Map<String, Object>> buildDepartmentTree(List<Department> departments) {
        // 按父ID分组
        Map<Long, List<Department>> departmentMap = departments.stream()
                .collect(Collectors.groupingBy(dept -> dept.getParentId() != null ? dept.getParentId() : 0L));
        
        // 构建树形结构（从根节点开始）
        return buildDepartmentTreeNodes(0L, departmentMap);
    }
    
    /**
     * 递归构建科室树节点
     * @param parentId 父级ID
     * @param departmentMap 按父ID分组的科室Map
     * @return 树节点列表
     */
    private List<Map<String, Object>> buildDepartmentTreeNodes(Long parentId, Map<Long, List<Department>> departmentMap) {
        List<Map<String, Object>> nodes = new ArrayList<>();
        List<Department> children = departmentMap.get(parentId);
        
        if (children != null) {
            for (Department dept : children) {
                Map<String, Object> node = new HashMap<>();
                node.put("id", dept.getId());
                node.put("name", dept.getName());
                node.put("code", dept.getCode());
                node.put("description", dept.getDescription());
                node.put("location", dept.getLocation());
                node.put("phone", dept.getPhone());
                node.put("headDoctorId", dept.getHeadDoctorId());
                node.put("status", dept.getStatus());
                node.put("level", dept.getLevel());
                node.put("sortOrder", dept.getSortOrder());
                
                // 递归获取子节点
                List<Map<String, Object>> childNodes = buildDepartmentTreeNodes(dept.getId(), departmentMap);
                if (!childNodes.isEmpty()) {
                    node.put("children", childNodes);
                }
                
                nodes.add(node);
            }
        }
        
        return nodes;
    }
} 